package com.misboot.document.controller;

import cn.ewsd.common.annotation.ControllerLog;
import cn.ewsd.common.utils.JsonUtils;
import cn.ewsd.common.utils.StringUtils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.misboot.document.model.OssFile;
import com.misboot.document.model.OssPageParam;
import com.misboot.document.service.OssFileService;
import com.misboot.document.service.OssService;
import com.misboot.document.utils.file.FileUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;


/**
 * 阿里云OSS文件上传管理
 *
 * @Author 湖南佐佑时代科技有限公司
 * @Version 5.4.21
 * @Email service@zuoyo.com
 * @Date 2022-06-13 09:39:40
 */
@Api(tags = {"阿里云OSS"})
@Controller
@RequestMapping("/oss")
@RefreshScope
public class AliyunOssController extends DocumentBaseController {

    static Logger logger = LoggerFactory.getLogger(AliyunOssController.class);


    @Autowired
    private OssService ossService;

    @Autowired
    private OssFileService ossFileService;

    /**
     * endpoint
     */
    @Value("${oss.endpoint:http://oss-cn-shanghai.aliyuncs.com}")
    private String endpoint;


    @ResponseBody
    @RequestMapping(value = "getBucketList", method = RequestMethod.POST)
    @ControllerLog(description = "获取Bucket列表")
    @ApiOperation(value = "获取桶列表")
    public List<Map<String, String>> getBucketList() {
        try {
            List<Bucket> bucketsList = ossService.listBuckets(endpoint);
            List<Map<String, String>> dataList = new ArrayList<Map<String, String>>();
            for (Bucket bucket : bucketsList) {
                Map<String, String> map = new HashMap<>();
                map.put("name", bucket.getName());
                map.put("location", bucket.getLocation());
                map.put("extranetEndpoint", bucket.getExtranetEndpoint());
                dataList.add(map);
            }
            return dataList;
        } catch (Exception e) {
            return null;
        }
    }


    @ResponseBody
    @RequestMapping(value = "/getPageSet", method = RequestMethod.POST)
    @ControllerLog(description = "获取分页数据")
    @ApiOperation(value = "获取文件分页数据")
    public Map<String, Object> getPageSet(OssPageParam ossPageParam, String search) {
        if (ossPageParam.getBucketName() == null || ossPageParam.getBucketName().trim().isEmpty()) {
            return null;
        }
        Map<String, Object> resultMap = ossService.listObjectsRequest(ossPageParam, search);
        return resultMap;
    }


    @ResponseBody
    @RequestMapping(value = "/saveCatalog", method = RequestMethod.POST)
    @ControllerLog(description = "添加目录页面")
    @ApiOperation(value = "添加目录方法")
    public Object saveCatalog(String endpoint, String bucketName, String catalog, String keyPrefix) {
        ossService.CreateFolder(endpoint, bucketName, catalog, keyPrefix);
        return success("添加成功 ！");
    }

    @RequestMapping(value = "/download", method = RequestMethod.GET)
    @ControllerLog(description = "下载")
    @ApiOperation(value = "文件下载方法")
    public String download(String bucketName, String endpoint, String objectName, HttpServletResponse response) throws IOException {
        ossService.openOssClient(endpoint);
        OSSClient ossClient = ossService.getOssClient();
        try {
            // 调用ossClient.getObject返回一个OSSObject实例，该实例包含文件内容及文件元信息。
            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
            // 调用ossObject.getObjectContent获取文件输入流，可读取此输入流获取其内容。
            InputStream content = ossObject.getObjectContent();

            String[] objectNameArr = objectName.split("/");
            String fileName = new String(objectNameArr[objectNameArr.length - 1].getBytes("UTF-8"), "iso-8859-1");
            response.reset();
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");

            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

            int buffer = 1024 * 10;
            byte data[] = new byte[buffer];
            int read;
            while ((read = content.read(data)) != -1) {
                response.getOutputStream().write(data, 0, read);
            }
            response.getOutputStream().flush();
            response.getOutputStream().close();
            ossObject.close();
            ossClient.shutdown();
            return null;
        } catch (OSSException oe) {
            return oe.getMessage();
        } catch (ClientException ce) {
            return ce.getMessage();
        }
    }

    @ResponseBody
    @RequestMapping(value = "/delFile", method = RequestMethod.POST)
    @ControllerLog(description = "删除文件")
    @ApiOperation(value = "删除文件方法")
    public Object download(String[] uuids, String endpoint, String bucketName) {
        List<String> deletedObjects = ossService.deleteObjects(uuids, endpoint, bucketName);
        return success("删除成功！");
    }


    /**
     * @MethodName multiUpload
     * @Description 多文件上传
     * @Param bucketName  桶名
     * @Param endpoint
     * @Param request
     * @Return java.lang.Object
     * @Author 宋景民<songjingmin @ zuoyoutech.com>
     * @Date 2019/4/25 10:20
     */
    @ResponseBody
    @RequestMapping(value = "/multiUpload", method = RequestMethod.POST)
    @ControllerLog(description = "多文件上传")
    @ApiOperation(value = "多文件上传方法")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bucketName", value = "桶名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "endpoint", value = "端点", required = true, dataType = "String"),
            @ApiImplicitParam(name = "keyPrefix", value = "键前缀", required = true, dataType = "String")
    })
    public Object multiUpload(String bucketName, String endpoint, String keyPrefix, HttpServletRequest request, String puuid) {
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        if (CollUtil.isEmpty(files)) {
            return failure("上传文件不能为空！！！");
        }
        for (int i = 0; i < files.size(); i++) {
            if (ObjectUtil.isEmpty(files.get(i)) || files.get(i).getSize() <= 0) {
                return failure("上传文件不能为空！！！");
            }
        }
        MultipartFile file = null;
        BufferedOutputStream stream = null;
        String uuid = null;
        String fileName = null;
        List<String> url = new ArrayList<>();
        for (int i = 0; i < files.size(); i++) {
            file = files.get(i);
            if (!file.isEmpty()) {
                OssFile ossFile = new OssFile();
                // 获取文件名 ，用uuid
                uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
                fileName = file.getOriginalFilename().replace(" ", "");
                url.add("https://" + bucketName + "." + endpoint + "/" + fileName);
                ossFile.setFileName(fileName);
                if (!StringUtils.isNullOrEmpty(keyPrefix) && !"undefined".equals(keyPrefix)) {
                    fileName = keyPrefix + fileName;
                }
                ossFile.setKeyPrefix(keyPrefix);
                ossFile.setBucketName(bucketName);
                ossFile.setEndpoint(endpoint);
                ossFile.setPuuid(puuid);
                ossFile.setKeyUrl(fileName);
                ossFile.setFileSize(FileUtils.getSize(file.getSize()));
                getSaveData(ossFile);
                try {
                    ossService.putObject(bucketName, endpoint, fileName, file.getBytes());
                    ossFileService.insertSelective(ossFile);
                } catch (IOException e) {
                    System.out.println("失败" + e.getMessage());
                    return failure("第 " + i + " 个文件上传失败.【原因】" + e.getMessage());
                }
            } else {
                return failure("第 " + i + " 个文件上传失败因为文件为空");
            }
        }
        HashMap var3 = new HashMap();
        var3.put("statusCode", 200);
        var3.put("title", "上传成功");
        var3.put("message", "上传成功！！！");
        var3.put("puuid", puuid);

        //处理表单预览
        var3.put("url", url);
        return var3;
    }

    @ResponseBody
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ControllerLog(description = "上传头像")
    @ApiOperation(value = "上传头像")
    public Object uploadAvatar(@RequestParam("file") MultipartFile file) {
        try {
            String bucketName = "zysd-emis"; //
            String endpoint = "oss-cn-shanghai.aliyuncs.com"; //
            String keyPrefix = "user/avatar/" + getCurrentUserNameId() + "/";

            if (file.isEmpty()) {
                return failure("上传失败，请选择文件");
            }
            String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
            String fileName = file.getOriginalFilename();
            String[] strArray = fileName.split("\\.");
            String suffixName = null;
            if ((strArray.length - 1) >= 0) {
                suffixName = strArray[strArray.length - 1];
            } else {
                suffixName = "";
            }
            //file.getSize() // long 获取文件大小
            String objectName = keyPrefix + uuid + "." + suffixName; // 文件名用文件UUID替换

            ossService.putObjectACL(bucketName, endpoint, objectName, file.getBytes());
            Map<String, Object> stringObjectMap = JsonUtils.messageJson(200, "操作提示", "上传成功");
            stringObjectMap.put("filePath", "https://" + bucketName + "." + endpoint + "/" + objectName);
            return stringObjectMap;
        } catch (OSSException | IOException oe) {
            return failure(oe.getMessage());
        } catch (ClientException ce) {
            return failure(ce.getMessage());
        } catch (Exception e) {
            return failure(e.getMessage());
        }
    }


    /**
     * @MethodName moveFile
     * @Description oss移动文件到桶
     * @Param sourceBucketName   源桶
     * @Param sourceKey 文件名
     * @Param destinationBucketName  目标桶
     * @Param endpoint  端点
     * @Return java.lang.Object
     * @Author 湖南佐佑时代科技有限公司<service @ zuoyo.com>
     * @Date 2020-10-22 11:36
     */
    @ResponseBody
    @RequestMapping(value = "/ossFileMoveBucket")
    public Object ossFileMoveBucket(String sourceBucketName, String sourceKey, String destinationBucketName, String endpoint) {
        return ossService.ossFileMoveBucket(sourceBucketName, sourceKey, destinationBucketName, endpoint);
    }


    /**
     * @MethodName ossMoveFiles
     * @Description oss 文件移动到文件夹下
     * @Param sourceBucketName
     * @Param sourceKey
     * @Param destinationBucketName
     * @Param endpoint
     * @Return java.lang.Object
     * @Author 湖南佐佑时代科技有限公司<service @ zuoyo.com>
     * @Date 2020-10-22 17:41
     */
    @ResponseBody
    @RequestMapping(value = "/ossFileMoveFolder")
    public Object ossFileMoveFolder(String sourceBucketName, String sourceKey, String destinationBucketName, String endpoint, String destinationKey) {
        return ossService.ossFileMoveFolder(sourceBucketName, sourceKey, destinationBucketName, endpoint, destinationKey);
    }


    /**
     * @MethodName wps文件上传到阿里云oss
     * @Description
     * @Param file
     * @Return java.lang.Object
     * @Date 2020/12/10 9:27 上午
     */
    @ResponseBody
    @RequestMapping(value = "/wpsOssUpload", method = RequestMethod.POST)
    public Object wpsOssUpload(@RequestPart("file") MultipartFile file) {
        String bucketName = "zysd-test1";
        String endpoint = "oss-cn-beijing.aliyuncs.com";
        String keyPrefix = null;
        try {

            if (file.isEmpty()) {
                return failure("上传失败，请选择文件");
            }
            String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
            String fileName = file.getOriginalFilename();
            String[] strArray = fileName.split("\\.");
            String suffixName = null;
            if ((strArray.length - 1) >= 0) {
                suffixName = strArray[strArray.length - 1];
            } else {
                suffixName = "";
            }
            //file.getSize() // long 获取文件大小
            String objectName = fileName; // 文件名用文件UUID替换

            ossService.putObjectACL(bucketName, endpoint, objectName, file.getBytes());
            Map<String, Object> stringObjectMap = JsonUtils.messageJson(200, "操作提示", "上传成功");
            stringObjectMap.put("filePath", "https://" + bucketName + "." + endpoint + "/" + objectName);
            logger.info("上传地址filePath" + "https://" + bucketName + "." + endpoint + "/" + objectName);
            return stringObjectMap;
        } catch (OSSException | IOException oe) {
            logger.info("上传错误" + oe.getMessage());
            return failure(oe.getMessage());
        } catch (ClientException e) {
            logger.info("上传错误" + e.getMessage());
            return failure(e.getMessage());
        } catch (Exception e) {
            logger.info("上传错误" + e.getMessage());
            return failure(e.getMessage());
        }
    }

}
